/*
 * @Description: 获取ADC值
 * @Author: diyhome
 * @Date: 2020-08-11 20:59
 * @File: get_adc_value
*/

#include "get_adc_value.h"

uint32_t AD_Buf[ADC_BUFFER_SIZE] = {0};
uint16_t AD_Value[4];

/**
 * 希尔排序
 * @param num_group 待排序数组指针
 * @param num_length 待排序数组长度
 */
static void ShellSort(uint32_t *num_group, uint8_t num_length) {
    int dk, i, j, temp;
    //小组的个数，小组的个数从n/2个，变成n/4，再变变变，越来越少，直到变成一个
    for (dk = ADC_BUFFER_SIZE / 5; dk >= 1; dk = dk / 2) {
        //因为这个小组的元素使隔了dk个，所以排的时候也要隔dk个
        //有点像归并排序
        for (i = dk; i < num_length; i++) {
            if (num_group[i] < num_group[i - dk]) {
                temp = num_group[i];
                for (j = i - dk; j >= 0 && temp < num_group[j]; j -= dk) {
                    num_group[j + dk] = num_group[j];
                }
                num_group[j + dk] = temp;
            }
        }
    }
}

/**
 * 滤波算法
 * @param num_group 待滤波数组
 * @param num_length 数组大小
 */
static uint16_t Filtering(uint32_t *num_group, uint8_t ad_index) {
    int x = num_group[ADC_BUFFER_SIZE / 10] - AD_Value[ad_index];
    if( ((unsigned)x - (unsigned)(-3)) <= 6) return AD_Value[ad_index];
    else return  num_group[ADC_BUFFER_SIZE / 10];
}

void Get_ADC_Value_Init(ADC_HandleTypeDef *adc) {
    HAL_ADCEx_Calibration_Start(adc);
    HAL_ADC_Start_DMA(adc, AD_Buf, ADC_BUFFER_SIZE);
}

void Get_ADC_Value() {
    // 定义四个数组存储AD转换值
    uint32_t adc_1[ADC_BUFFER_SIZE / 5] = {0};
    uint32_t adc_2[ADC_BUFFER_SIZE / 5] = {0};
    uint32_t adc_3[ADC_BUFFER_SIZE / 5] = {0};
    uint32_t adc_4[ADC_BUFFER_SIZE / 5] = {0};

    for (int i = 0; i < ADC_BUFFER_SIZE / 5; ++i) {
        adc_1[i] = AD_Buf[1 + 5 * i];
        adc_2[i] = AD_Buf[2 + 5 * i];
        adc_3[i] = AD_Buf[3 + 5 * i];
        adc_4[i] = AD_Buf[4 + 5 * i];
    }
    ShellSort(adc_1, ADC_BUFFER_SIZE / 5);
    ShellSort(adc_2, ADC_BUFFER_SIZE / 5);
    ShellSort(adc_3, ADC_BUFFER_SIZE / 5);
    ShellSort(adc_4, ADC_BUFFER_SIZE / 5);

    AD_Value[0] = Filtering(adc_1, 0);
    AD_Value[1] = Filtering(adc_2, 1);
    AD_Value[2] = Filtering(adc_3, 2);
    AD_Value[3] = Filtering(adc_4, 3);
}
